package com.example.springboottestgit.service;

import com.alibaba.fastjson.JSONObject;
import com.example.springboottestgit.bean.BusinessException;
import com.example.springboottestgit.bean.EconomicContentQaRecord;
import com.example.springboottestgit.bean.dto.EconomicPolicyDTO;
import com.example.springboottestgit.bean.vo.EconomicPolicyVO;
import com.example.springboottestgit.bean.vo.InputVO;
import com.example.springboottestgit.bean.vo.OutputVO;
import com.example.springboottestgit.dao.EconomicContentQaRecordMapper;
import com.example.springboottestgit.enums.ExceptionCodeEnum;
import com.example.springboottestgit.utils.FileUtil;
import com.example.springboottestgit.utils.HttpUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;

/**
 * @description:
 * @author: ZZZ
 */
@Slf4j
@Service
public class EconomicPolicyModelService {

    @Value("${economic.policy.mode.url}")
    private String economicPolicyModeUrl;

    @Value("${economic.horizon.mode.url}")
    private String economicHorizonModeUrl;

    @Value("${file.save.path}")
    private String fileSavePath;

    @Value("${index.name}")
    private String indexName;

    @Value("${es.query.size}")
    private Integer esQuerySize;

    @Autowired
    private EconomicContentQaRecordMapper economicContentQaRecordMapper;

    @Autowired
    private ElasticSearchClientServer elasticSearchClientServer;


    public long save(EconomicPolicyDTO dto) {
        EconomicContentQaRecord insert = new EconomicContentQaRecord();
        insert.setType(dto.getType());
        if (dto.getId() != null) {
            insert.setAssoId(dto.getId());
        }

        insert.setQuestion(dto.getQuestion());
        economicContentQaRecordMapper.insert(insert);
        return insert.getId();

    }

    @Async("myAsync")
    public void economicPolicyAsk(EconomicPolicyDTO dto) {
        EconomicContentQaRecord update = new EconomicContentQaRecord();
        update.setId(dto.getId());
        update.setType(dto.getType());
        try {
            log.info("===========经济大模型提问=============");
            LocalDateTime s = LocalDateTime.now();
            //构建接口参数
            InputVO inputVO = new InputVO();
            String url = "";
            //1-经济政策；2-经济视界
            //String url = "1".equals(dto.getType()) ? economicPolicyModeUrl : economicHorizonModeUrl;
            if ("1".equals(dto.getType())) {
                url = economicPolicyModeUrl;
                //es 查询文件内容保存到本地
                String uuid = String.valueOf(UUID.randomUUID()).replace("-", "");
                String path = fileSavePath + uuid + ".txt";
                log.info(dto.getQuestion());
                log.info(path);
                //update.setFilePath(path);
                //inputVO.setFilePath(path);
                //String content = elasticSearchClientServer.queryContent(indexName, dto, esQuerySize);
                List<String> list = elasticSearchClientServer.queryContent(indexName, dto, esQuerySize);
                inputVO.setDocuments(list);
                StringBuilder sb = new StringBuilder("");
                for (String eps : list) {
                    sb.append(eps).append("\n\n*******************************************************\n\n");
                }
                FileUtil.txtWriter(path, sb.toString());

            } else {
                url = economicHorizonModeUrl;
            }
            inputVO.setQuestion(dto.getQuestion());
            //inputVO.setStartYear(dto.getStartYear());
            //inputVO.setEndYear(dto.getEndYear());

            String param = JSONObject.toJSONString(inputVO);
            //log.info("参数：{}", param);
            String result = HttpUtils.post(url, param);
            OutputVO outputVO = JSONObject.parseObject(result, OutputVO.class);
            if (!"000000".equals(outputVO.getCode())) {
                log.error("经济政策模型接口调用失败,返回结果：{}", result);
                throw new BusinessException(ExceptionCodeEnum.INTERFACE_CALL_FAIL.code, "经济政策模型接口调用失败");
            }
            log.info("回答：{}", result);
            update.setStatus(1);
            update.setAnswer(outputVO.getAnswer());
            LocalDateTime e = LocalDateTime.now();
            Duration between = Duration.between(s, e);
            economicContentQaRecordMapper.updateById(update);
            log.info("经济大模型接口调用耗时 {} 秒", between.getSeconds());
        } catch (Exception e) {
            update.setStatus(1);
            update.setAnswer("AI 机器人繁忙中，请先休息一下，稍后再提问吧");
            economicContentQaRecordMapper.updateById(update);
            log.error("经济大模型接口调用失败", e);
            throw new BusinessException(ExceptionCodeEnum.INTERFACE_CALL_FAIL.code, "经济政策大模型接口调用失败");
        }
    }

    public Map<String, String> test(EconomicPolicyDTO dto) {
        Map<String, String> map = new HashMap<>();
        String answer = "";
        String esMatch = "不匹配";
        String vectorMatch = "不匹配";
        try {
            log.info("===========经济大模型提问=============");
            LocalDateTime s = LocalDateTime.now();
            //构建接口参数
            InputVO inputVO = new InputVO();
            String url = "";
            //1-经济政策；2-经济视界
            //String url = "1".equals(dto.getType()) ? economicPolicyModeUrl : economicHorizonModeUrl;

            url = economicPolicyModeUrl;
            //es 查询文件内容保存到本地
            String uuid = String.valueOf(UUID.randomUUID()).replace("-", "");
            String path = fileSavePath + uuid + ".txt";
            log.info(dto.getQuestion());
            log.info(path);
            int h = 0;
            List<String> list = elasticSearchClientServer.queryContent(indexName, dto, esQuerySize);
            if (dto.getFileName() != null && dto.getFileName().length() > 3) {
                for (String s1 : list) {
                    h++;
                    if (s1.contains(dto.getFileName().replace(".txt", ""))) {
                        esMatch = "匹配,出现位置：" + h;
                        break;
                    }
                }
            }

            inputVO.setDocuments(list);
            StringBuilder sb = new StringBuilder("");
            for (String eps : list) {
                sb.append(eps).append("\n\n*******************************************************\n\n");
            }
            FileUtil.txtWriter(path, sb.toString());


            inputVO.setQuestion(dto.getQuestion());

            String param = JSONObject.toJSONString(inputVO);
            //log.info("参数：{}", param);
            String result = HttpUtils.post(url, param);
            OutputVO outputVO = JSONObject.parseObject(result, OutputVO.class);
            if (!"000000".equals(outputVO.getCode())) {
                log.error("经济政策模型接口调用失败,返回结果：{}", result);
                throw new BusinessException(ExceptionCodeEnum.INTERFACE_CALL_FAIL.code, "经济政策模型接口调用失败");
            }
            answer = outputVO.getAnswer();

            String documents = "";
            int k = 0;
            for (OutputVO.VectorDocument vectorDocument : outputVO.getReranked_results()) {
                k++;
                if (k > 3) {
                    break;
                }
                String txt = "分数：" + vectorDocument.getScore() + "\n" + vectorDocument.getDocument() + "\n\n";
                documents = documents + txt;
            }
            map.put("document", documents);

            int v = 0;
            if (dto.getFileName() != null && dto.getFileName().length() > 3) {
                for (OutputVO.VectorDocument vectorDocument : outputVO.getReranked_results()) {
                    String s1 = vectorDocument.getDocument();
                    v++;
                    if (s1.contains(dto.getFileName().replace(".txt", ""))) {
                        vectorMatch = "匹配,出现位置：" + v;
                        break;
                    }
                }
            }
            map.put("vectorMatch", vectorMatch);

            log.info("回答：{}", answer);
            log.info("document长度：{}", documents.length());
            LocalDateTime e = LocalDateTime.now();
            Duration between = Duration.between(s, e);
            log.info("经济大模型接口调用耗时 {} 秒", between.getSeconds());
        } catch (Exception e) {
            log.error(e.getMessage());
            answer = "AI 机器人繁忙中，请先休息一下，稍后再提问吧";
        }
        map.put("answer", answer);
        map.put("esMatch", esMatch);
        return map;
    }


    public EconomicPolicyVO economicPolicyQuery(long id) {
        return economicContentQaRecordMapper.economicPolicyQuery(id);
    }

    public List<EconomicPolicyVO> economicPolicyQueryList(long assoId) {
        List<EconomicPolicyVO> list = new ArrayList<>();
        EconomicPolicyVO vo = economicContentQaRecordMapper.economicPolicyQuery(assoId);
        if (vo != null) {
            list.add(vo);
            list.addAll(economicContentQaRecordMapper.economicPolicyQueryList(assoId));
        }
        return list;
    }
}
